package com.such.kit.database.dialect;

import com.such.kit.Callable;
import com.such.kit.cache.CacheCommons;
import com.such.kit.string.StringCommons;

/**
 * @作者 SUCH
 * @日期 2017-6-9 下午3:46:28
 * @描述 SQL 语句方言处理工具类
 * <p>
 * 配置方式：<br>
 * 每种数据库对应一个 properties 文件<br>
 * oracle > oracle.properties<br>
 * db2 > db2.properties<br>
 * mysql > mysql.properties<br>
 * sqlserver > sqlserver.properties<br>
 * properties 文件中以方法名作 key，可以格式化资源值
 * </p>
 */
public class DialectCommons {

	/** RESERVED_WORD：数据库保留字 */
	public final ReservedWordFactory RESERVED_WORD;
	/** TYPE：数据库数据类型 */
	public final TypeFactory TYPE;
	/** FORMAT：数据库数据格式 */
	public final FormatFactory FORMAT;
	/** FUNC：数据库函数 */
	public final FuncFactory FUNC;
	/** DDL：数据库定义语句 */
	public final DDLFactory DDL;
	/** SQL：SQL 语句 */
	public final SqlFactory SQL;

	private static String dialectCache = CacheCommons.buildCacheName(DialectCommons.class);

	private String resourceName;

	/**
	 * <p>方法名：getInstance</p>
	 * <p>描述：获取 DialectCommons 实例</p>
	 * @param dbType 数据库类型，取 MetaDataCommons.DB_TYPE_* 常量
	 * @return DialectCommons 实例
	 * @throws Exception 
	 */
	public static DialectCommons getInstance(final String dbType) throws Exception {
		DialectCommons dialect = CacheCommons.get(dialectCache, dbType, new Callable<String, DialectCommons>() {
			@Override
			public DialectCommons call(String param) throws Exception {
				return new DialectCommons(dbType);
			}
		});
		return dialect;
	}

	/**
	 * <p>构造函数</p>
	 * <p>描述：私有构造函</p>
	 * @param dbType 数据库类型，取 MetaDataCommons.DB_TYPE_* 常量
	 */
	private DialectCommons(String dbType) {
		this.resourceName = StringCommons.merger("com.such.kit.database.dialect.configs.", dbType);
		this.RESERVED_WORD = new ReservedWordFactory(this.resourceName);
		this.TYPE = new TypeFactory(this.resourceName);
		this.FORMAT = new FormatFactory(this.resourceName);
		this.FUNC = new FuncFactory(this.resourceName);
		this.DDL = new DDLFactory(this.resourceName);
		this.SQL = new SqlFactory(this.resourceName);
	}

}
